home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Online / hsc / source / hsclib / idref.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-02  |  5.3 KB  |  226 lines

  1. /*
  2.  * This source code is part of hsc, a html-preprocessor,
  3.  * Copyright (C) 1995-1997  Thomas Aglassinger
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20. /*
  21.  * hsclib/idref.c
  22.  *
  23.  * functions for id-references
  24.  *
  25.  * updated: 14-Oct-1996
  26.  * created: 12-Apr-1995
  27.  *
  28.  */
  29.  
  30. #include "hsclib/inc_base.h"
  31.  
  32. #include <stdarg.h>
  33. #include "ugly/ustrlist.h"
  34.  
  35. #include "hscprj/document.h"
  36. #define NOEXTERN_HSCLIB_ID_H
  37. #include "hsclib/idref.h"
  38.  
  39. #if DEBUG_ID
  40. #define DIHP(x) if ( hp->debug ) x
  41. #define DI(x)   x
  42. #else
  43. #define DIHP(x)                 /* nufin */
  44. #define DI(x)                   /* nufin */
  45. #endif
  46.  
  47. /* hsc_msg_unknown_id: warning about unknown id-refrence */
  48. VOID hsc_msg_unknown_id(HSCPRC * hp, STRPTR filename, STRPTR id)
  49. {
  50.     if (filename)
  51.         hsc_message(hp, MSG_UNKN_ID, "unknown id `%s#%s'",
  52.                     filename, id);
  53.     else
  54.         hsc_message(hp, MSG_UNKN_ID, "unknown id %q", id);
  55. }
  56.  
  57. /* macros for local compare-callbacks */
  58. #define cmp_idname cmp_string_node
  59. #define cmp_idref cmp_string_node
  60. #define cmp_id_local cmp_string_node
  61.  
  62. /*
  63.  *
  64.  * new- and del-methodes
  65.  *
  66.  */
  67.  
  68. /*
  69.  * del/new_idref
  70.  */
  71.  
  72. /* del_idref: remove referenced id */
  73. VOID del_idref(APTR data)
  74. {
  75.     IDREF *idref = (IDREF *) data;
  76.  
  77.     ufreestr(idref->name);
  78.     del_infilepos(idref->fpos);
  79.     ufree(idref);
  80. }
  81.  
  82. /* new_id_local: create new reference to local id  */
  83. static IDREF *new_idref(STRPTR id, INFILEPOS * fpos)
  84. {
  85.     IDREF *newid = (IDREF *) umalloc(sizeof(IDREF));
  86.  
  87.     newid->name = strclone(id);
  88.     newid->fpos = fpos;
  89.  
  90.     return (newid);
  91. }
  92.  
  93. VOID prt_idref(FILE * stream, APTR data)
  94. {
  95.     IDREF *idref = (IDREF *) data;
  96.     INFILEPOS *fpos = idref->fpos;
  97.  
  98.     fprintf(stream, "`%s' at (%lu,%lu)\n",
  99.             idref->name, ifp_get_y(fpos), ifp_get_x(fpos));
  100. }
  101.  
  102. /*
  103.  * add_local_iddef
  104.  *
  105.  * define a new local ID that can be refered to
  106.  */
  107. BOOL add_local_iddef(HSCPRC * hp, STRPTR id)
  108. {
  109.     INFILEPOS *fpos = new_infilepos(hp->inpf);
  110.     HSCIDD *iddef = find_iddef(hp->project->document, id);
  111.  
  112.     DIHP(fprintf(stderr, DHL "add ref to id `%s' at `%s' (%lu,%lu)\n",
  113.                  id, ifp_get_fname(fpos),
  114.                  ifp_get_y(fpos), ifp_get_x(fpos)));
  115.  
  116.     /* check for duplicate definition */
  117.  
  118.     if (iddef)
  119.     {
  120.         /* duplicate definition */
  121.         DIHP(fprintf(stderr, DHL "    duplicate definition\n"));
  122.  
  123.         hsc_message(hp, MSG_REDEFINE_ID,
  124.                     "local id %q already declared", id);
  125.  
  126.         set_infilepos(hp->inpf, iddef->fpos);
  127.         hsc_message(hp, MSG_REDEFINE_ID,
  128.                     "(location of previous declaration)");
  129.  
  130.         set_infilepos(hp->inpf, fpos);
  131.         del_infilepos(fpos);
  132.     }
  133.     else
  134.     {
  135.         /* remember new local id */
  136.         iddef = app_iddef(hp->project->document, id);
  137.         iddef->caller = fpos2caller(fpos);
  138.         iddef->fpos = fpos;
  139.  
  140.         DIHP(fprintf(stderr, DHL "    append to local iddefs\n"));
  141.     }
  142.  
  143.     return (TRUE);
  144. }
  145.  
  146. /*
  147.  * check_id_local
  148.  *
  149.  * append id to idref-list so it as checked when
  150.  * check_all_local_idref() is called
  151.  */
  152. VOID add_local_idref(HSCPRC * hp, STRPTR id)
  153. {
  154.     INFILEPOS *fpos = new_infilepos(hp->inpf);
  155.  
  156.     DIHP(fprintf(stderr, DHL "  check id: `#%s' (local)\n", id));
  157.     DIHP(fprintf(stderr, DHL "    append to idref\n"));
  158.     app_dlnode(hp->idrefs, new_idref(id, fpos));
  159. }
  160.  
  161. /*
  162.  * check_local_idref
  163.  */
  164. static BOOL check_local_idref(HSCPRC * hp, IDREF * idref)
  165. {
  166.     HSCIDD *iddef = find_iddef(hp->project->document, idref->name);
  167.     BOOL found = FALSE;
  168.  
  169.     if (iddef)
  170.     {
  171.         found = TRUE;
  172.         DIHP(fprintf(stderr, DHL " local id ok: `%s'\n", idref->name));
  173.     }
  174.     else
  175.     {
  176.         DIHP(
  177.                 {
  178.                 INFILEPOS * fpos = idref->fpos;
  179.                 fprintf(stderr, DHL " local id unknown: `%s' (%lu,%lu)\n",
  180.                         idref->name, ifp_get_y(fpos), ifp_get_x(fpos));
  181.                 }
  182.         );
  183.  
  184.         set_infilepos(hp->inpf, idref->fpos);
  185.         hsc_msg_unknown_id(hp, NULL, idref->name);
  186.     }
  187.  
  188.     return (found);
  189. }
  190.  
  191. /*
  192.  * check_all_local_idref
  193.  */
  194. BOOL check_all_local_idref(HSCPRC * hp)
  195. {
  196.     BOOL ok = TRUE;
  197.     DLNODE *nd = NULL;
  198.     INFILEPOS *infpos = new_infilepos(hp->inpf);
  199.  
  200.     DIHP(fprintf(stderr, DHL "check local IDs\n"));
  201.  
  202.     DIHP(
  203.             {
  204.  
  205.             fprintf(stderr, DHL " local IDs defined:\n");
  206.             fprintf_dllist(stderr, hp->project->document->iddefs, prt_iddef);
  207.             fprintf(stderr, DHL " local IDs referenced:\n");
  208.             fprintf_dllist(stderr, hp->idrefs, prt_idref);
  209.  
  210.             }
  211.     );
  212.  
  213.     nd = dll_first(hp->idrefs);
  214.     while (nd)
  215.     {
  216.         check_local_idref(hp, ((IDREF *) nd->data));
  217.         nd = dln_next(nd);
  218.     }
  219.  
  220.     set_infilepos(hp->inpf, infpos);
  221.     del_infilepos(infpos);
  222.  
  223.     return (ok);
  224. }
  225.  
  226.